﻿namespace com.stifel.BranchMgmtDao
{
    using System;
    using System.Collections.Generic;
    using System.Linq;

    using com.stifel.Extensions.SharePointExtensions;
    using com.stifel.Extensions.SymbolExtensions;
    using com.stifel.SharePoint;

    using Microsoft.SharePoint;
    using Microsoft.SharePoint.Linq;

    using Context = BranchMgmtDataContext;

    using CustomObject = StifelBranchUpdate;

    public class StifelBranchUpdateDao : StifelBaseDao
    {
        #region Fields

        public const string ListName = "stifelbranchupdate";

        #endregion Fields

        #region Constructors

        public StifelBranchUpdateDao( )
            : base(ListName)
        {
            CurrentWebUrl = ConfiguredWebUrl;
        }

        public StifelBranchUpdateDao( string currentWebUrl )
            : base(ListName)
        {
            this.CurrentWebUrl = currentWebUrl;
        }

        #endregion Constructors

        #region Methods

        public CustomObject Add( CustomObject value )
        {
            using ( Context c = new Context( CurrentWebUrl ) )
            {
                EntityList<CustomObject> l = c.GetList<CustomObject>( ListTitle );
                string title = value.Title;
                List<SPFile> attachments = value.Attachments;
                Guid g = Guid.NewGuid( );
                value.Title = g.ToString( );
                l.InsertOnSubmit( clean( value ) );
                c.SubmitChanges( );
                CustomObject v = ( from o in l
                                   where o.Title == g.ToString( )
                                   select o ).SingleOrDefault( );
                v.Title = title;
                c.SubmitChanges( );

                if ( attachments != null && attachments.Count > 0 )
                    v.ListItem.AddAttachmentNow( attachments );

                return v;
            }
        }

        public CustomObject AddVersion( CustomObject value, Guid uniqueId )
        {
            using ( Context c = new Context( CurrentWebUrl ) )
            {
                EntityList<CustomObject> l = c.GetList<CustomObject>( ListTitle );
                CustomObject v = ( from o in l
                                   where o.UniqueId == uniqueId
                                   select o ).SingleOrDefault( );
                if ( v != null )
                {
                    v.BranchLookupId = value.BranchLookupId;
                    v.UpdateNotes = value.UpdateNotes;
                    v.Title = value.Title;
                    // commit changes
                    c.SubmitChanges( );
                    return v;
                }
                else
                    return null;
            }
        }

        public void Clear( )
        {
            using ( Context c = new Context( CurrentWebUrl ) )
            {
                EntityList<CustomObject> l = c.GetList<CustomObject>( ListTitle );
                var v = ( from o in l
                          where o.Id > 0
                          select o );
                if ( v.Count( ) > 0 )
                {
                    l.DeleteAllOnSubmit( v );
                    c.SubmitChanges( );
                }
            }
        }

        public void Delete( List<Guid> values )
        {
            using ( Context c = new Context( CurrentWebUrl ) )
            {
                EntityList<CustomObject> l = c.GetList<CustomObject>( ListTitle );
                foreach ( Guid g in values )
                {
                    CustomObject v = ( from o in l
                                       where o.UniqueId == g
                                       select o ).SingleOrDefault( );
                    if ( v != null )
                        l.DeleteOnSubmit( v );
                }
                c.SubmitChanges( );
            }
        }

        public List<CustomObject> GetAll( )
        {
            using ( Context c = new Context( CurrentWebUrl ) )
            {
                List<CustomObject> l = c.GetList<CustomObject>( ListTitle ).ToList( );
                return l;
            }
        }

        public List<CustomObject> GetByBranchLocation( int branchId )
        {
            List<CustomObject> allVersions = new List<CustomObject>( );
            using ( Context c = new Context( CurrentWebUrl ) )
            {
                EntityList<CustomObject> l = c.GetList<CustomObject>( ListTitle );
                List<CustomObject> v = ( from o in l
                                         where o.BranchLookupId == branchId
                                         select o ).ToList( );
                using ( SPSite spSite = new SPSite( CurrentWebUrl ) )
                {
                    using ( SPWeb spWeb = spSite.OpenWeb( ) )
                    {
                        SPList spList = spWeb.Lists.GetListByRootFolder( ListName );
                        foreach ( CustomObject o in v )
                        {
                            if ( o != null )
                            {
                                allVersions.AddRange( getAllVersions( spWeb, spList, o ) );
                            }
                        }
                    }
                }

                return allVersions;
            }
        }

        public CustomObject Update( CustomObject value )
        {
            using ( Context c = new Context( CurrentWebUrl ) )
            {
                EntityList<CustomObject> l = c.GetList<CustomObject>( ListTitle );
                CustomObject v = ( from o in l
                                   where o.UniqueId == value.UniqueId
                                   select o ).SingleOrDefault( );
                if ( v != null )
                {
                    v.BranchLookupId = value.BranchLookupId;
                    v.UpdateNotes = value.UpdateNotes;
                    v.Title = value.Title;
                    // commit changes
                    c.SubmitChanges( );
                    return v;
                }
                else
                    return null;
            }
        }

        CustomObject clean( CustomObject value )
        {
            return new CustomObject
            {
                BranchLookupId = value.BranchLookupId,
                Title = value.Title,
                UpdateNotes = value.UpdateNotes
            };
        }

        List<CustomObject> getAllVersions( SPWeb spWeb, SPList spList, CustomObject o )
        {
            List<CustomObject> list = new List<CustomObject>( );
            SPListItemVersionCollection col = o.ListItem.Versions;
            foreach ( SPListItemVersion w in col )
            {
                int versionId = w.VersionId;
                string versionLabel = w.VersionLabel;
                string updateNotes = Convert.ToString( w[ Item.GetColumnName<CustomObject>( o.GetPropertySymbol( a => a.UpdateNotes ) ) ] );
                string title = Convert.ToString( w[ Item.GetColumnName<CustomObject>( o.GetPropertySymbol( a => a.Title ) ) ] );
                SPFieldUserValue u = new SPFieldUserValue( spWeb, Convert.ToString( w[ Item.AUTHOR ] ) );
                SPUserInfoExpanded author = new SPUserInfoExpanded( u.User.Name, u.User.LoginName, u.User.Email, u.User.ID, u.User.Sid, u.User.Notes );
                u = new SPFieldUserValue( spWeb, Convert.ToString( w[ Item.EDITOR ] ) );
                SPUserInfoExpanded editor = new SPUserInfoExpanded( u.User.Name, u.User.LoginName, u.User.Email, u.User.ID, u.User.Sid, u.User.Notes );
                DateTime created = Convert.ToDateTime( w[ Item.CREATED ] );
                DateTime modified = Convert.ToDateTime( w[ Item.MODIFIED ] );
                int id = Convert.ToInt32( w[ Item.GetColumnName<CustomObject>( o.GetPropertySymbol( a => a.Id ) ) ] );
                Guid uniqueId = new Guid( Convert.ToString( w[ Item.UNIQUEID ] ) );
                string s = Convert.ToString( w[ Item.GetColumnName<CustomObject>( o.GetPropertySymbol( a => a.BranchLookupId ) ) ] );
                Guid parentListId = spList.ID;
                string displayUrl = spList.Forms[ PAGETYPE.PAGE_DISPLAYFORM ].Url;
                string webUrl = spWeb.Url;
                SPLookupValue branchId = new SPLookupValue( s );
                CustomObject co = new CustomObject
                {
                    Author = author,
                    BranchLookupId = branchId.LookupId,
                    BranchLookupTitle = branchId.LookupValue,
                    Created = created,
                    Editor = editor,
                    Id = id,
                    ItemUrl = string.Format( "{0}/{1}?ID={2}", webUrl, displayUrl, id ),
                    Modified = modified,
                    ParentListId = parentListId,
                    Title = title,
                    UpdateNotes = updateNotes,
                    UniqueId = uniqueId,
                    Version = versionId,
                    VersionLabel = versionLabel,
                    WebUrl = webUrl
                };
                list.Add( co );
            }
            return list;
        }

        #endregion Methods
    }
}